﻿using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;

namespace Pscx
{
    /// <summary>
    /// Utility class to convert .NET async callbacks to events that can be sunk by v2.0 eventing.
    /// </summary>
    public sealed class PscxCallbackEventBridge
    {
        private readonly string _bridgeId;

        /// <summary>
        /// Raised when the .NET callback delegate is invoked.
        /// </summary>
        public event AsyncCallback CallbackComplete = delegate { };

        private PscxCallbackEventBridge(string bridgeId)
        {
            _bridgeId = bridgeId;
            Trace.WriteLine("Callcback .ctor", bridgeId);
        }

        private void CallbackInternal(IAsyncResult result)
        {
            Trace.WriteLine("Callback Enter", _bridgeId);
            CallbackComplete(result);
            Trace.WriteLine("Callback Exit", _bridgeId);
        }

        /// <summary>
        /// Delegate to pass to method expecting an AsyncCallback parameter.
        /// </summary>
        public AsyncCallback Callback
        {
            get
            {
                return new AsyncCallback(CallbackInternal);
            }
        }

        /// <summary>
        /// Create an event callback bridge with an autogenerated tracing identifier.
        /// </summary>
        /// <returns>An instance of the PscxCallbackEventBridge class.</returns>
        public static PscxCallbackEventBridge Create()
        {
            string bridgeId = String.Format("eventBridge_{0}", Guid.NewGuid());

            return new PscxCallbackEventBridge(bridgeId);
        }

        /// <summary>
        /// Create an event callback bridge with an user defined tracing identifier.
        /// </summary>
        /// <param name="bridgeId">A string identifier that will be used in internal Trace.WriteLine calls (useful for debugging.)</param>
        /// <returns>An instance of the PscxCallbackEventBridge class.</returns>
        public static PscxCallbackEventBridge Create(string bridgeId)
        {
            if (String.IsNullOrEmpty(bridgeId))
            {
                throw new ArgumentException("parameter bridgeId is null or empty.");
            }

            return new PscxCallbackEventBridge(bridgeId);
        }
    }
}
